home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / program / wdj0897.zip / TOMLINSN.ZIP / WDJSRVC.C < prev   
C/C++ Source or Header  |  1997-05-29  |  7KB  |  246 lines

  1. /*
  2.  bcc32 -w -DSTRICT clnt.c
  3.  bcc32 -w -DSTRICT wdjsrvc.c
  4.    ---OR---
  5.  cl /W3 /DSTRICT clnt.c user32.lib
  6.  cl /W3 /DSTRICT wdjsrvc.c advapi32.lib user32.lib
  7. */
  8.  
  9.  
  10.  
  11. #define UNICODE
  12. #define _UNICODE
  13. #include <windows.h>
  14. #include <stdlib.h>
  15. #include <stdio.h>
  16.  
  17.  
  18. BOOL NotifySCM(DWORD, DWORD, DWORD);
  19. VOID WINAPI ServiceMain(DWORD, LPTSTR *);
  20. VOID WINAPI ServiceHandler(DWORD);
  21. DWORD WINAPI WorkerThread(LPVOID);
  22. VOID ProcessData(LPVOID Buffer, ULONG Size);
  23. BOOL IsThreadAdmin(void);
  24.  
  25. HANDLE  hDoneEvent = NULL, hThread = NULL;
  26. DWORD   dwCurrentState;
  27. SERVICE_STATUS_HANDLE  hService;
  28.  
  29. //--------------------------------------------------------------------
  30. void main(void)
  31. {
  32.     SERVICE_TABLE_ENTRY ServiceTable[] = 
  33.         {{TEXT("WDJSrvc"), ServiceMain}, {NULL, NULL}};
  34.  
  35.     StartServiceCtrlDispatcher(ServiceTable);
  36. } // main
  37.  
  38. //------------------------------------------------------------------
  39. #ifdef __BORLANDC__
  40. #   pragma  argsused
  41. #endif
  42. VOID WINAPI ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv)
  43. {
  44.     DWORD   ThreadId;
  45.  
  46.     hService = RegisterServiceCtrlHandler(TEXT("WDJSrvc"), ServiceHandler);
  47.     if (!hService) {
  48.         return;
  49.     }
  50.  
  51.     NotifySCM(SERVICE_START_PENDING, 0, 1);
  52.  
  53.     hDoneEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  54.     if (!hDoneEvent) {
  55.         return;
  56.     }
  57.  
  58.     hThread = CreateThread(0, 0, WorkerThread, 0, 0, &ThreadId);
  59.     if (!hThread) {
  60.         CloseHandle(hDoneEvent);
  61.         return;
  62.     }
  63.  
  64.     NotifySCM(SERVICE_RUNNING, 0, 0);
  65.  
  66.     WaitForSingleObject(hDoneEvent, INFINITE);
  67.     CloseHandle(hThread);
  68.     CloseHandle(hDoneEvent);
  69.     return;
  70. } // ServiceMain
  71.  
  72. //------------------------------------------------------------------
  73. #ifdef __BORLANDC__
  74. #   pragma argsused
  75. #endif
  76. DWORD WINAPI WorkerThread(LPVOID ThreadParam)
  77. {
  78.     TCHAR  Buffer[1024];
  79.     HANDLE hPipe;
  80.     ULONG  Status, Size;
  81.     PSECURITY_DESCRIPTOR pSecDesc;
  82.     SECURITY_ATTRIBUTES SecAttr;
  83.  
  84.     //
  85.     // Create a security descriptor that gives access to EVERYONE
  86.     //
  87.     pSecDesc = malloc(SECURITY_DESCRIPTOR_MIN_LENGTH);
  88.     InitializeSecurityDescriptor(pSecDesc, 
  89.                                  SECURITY_DESCRIPTOR_REVISION);
  90.     SetSecurityDescriptorDacl(pSecDesc, TRUE, (PACL)NULL, FALSE);
  91.     SecAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
  92.     SecAttr.lpSecurityDescriptor = pSecDesc;
  93.     SecAttr.bInheritHandle = FALSE;
  94.     
  95.     //
  96.     // create an instance of the pipe that we reuse for each client
  97.     //
  98.     hPipe = CreateNamedPipe(TEXT("\\\\.\\pipe\\wdjpipe1"),
  99.             PIPE_ACCESS_DUPLEX | FILE_FLAG_WRITE_THROUGH,
  100.             PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 
  101.             PIPE_UNLIMITED_INSTANCES, 1024, 1024, 20000, &SecAttr);
  102.     if (hPipe == INVALID_HANDLE_VALUE) {
  103.         return FALSE;
  104.     }
  105.     
  106.     while(TRUE) {
  107.         //
  108.         // Wait for a client to connect to this instance of the pipe
  109.         //
  110.         if (ConnectNamedPipe(hPipe, NULL) ||
  111.             GetLastError() == ERROR_PIPE_CONNECTED) {
  112.  
  113.             while (TRUE) {
  114.                 //
  115.                 // Read client requests from the pipe. 
  116.                 //
  117.                 Status = ReadFile(hPipe, Buffer, 1024, &Size, NULL); 
  118.                 if (Status && (Size > 0)) {
  119.                     ImpersonateNamedPipeClient(hPipe);
  120.                     ProcessData(Buffer, Size);
  121.                     WriteFile(hPipe, Buffer, Size, &Size, NULL);
  122.                 } else {
  123.                     break;
  124.                 }
  125.             }
  126.  
  127.             RevertToSelf();
  128.             // let client read before disconnect
  129.             FlushFileBuffers(hPipe);
  130.             DisconnectNamedPipe(hPipe); 
  131.         }
  132.     } 
  133.  
  134. } // WorkerThread
  135.  
  136. //------------------------------------------------------------------
  137. VOID ProcessData(LPVOID Buffer, ULONG Size)
  138. {
  139.     INT    Result;
  140.     LPWSTR UniBuffer = malloc(Size * sizeof(WCHAR));  // worst case
  141.     BOOL bUnicode = IsTextUnicode(Buffer, Size, &Result);
  142.     
  143.     if (IsThreadAdmin()) {  // based on Q118626
  144.         //
  145.         // Access allowed so process data, converting to unicode if
  146.         // necessary.
  147.         //
  148.         if (bUnicode) {   
  149.             lstrcpy(UniBuffer, (LPCTSTR)Buffer);
  150.         } else {
  151.             MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, Buffer,
  152.                     Size, UniBuffer, Size);
  153.         }
  154.         CharUpper(UniBuffer);   // this is our trivial processing!!
  155.  
  156.     } else {
  157.         lstrcpy(UniBuffer, L"ACCESS DENIED");
  158.     }
  159.  
  160.     if (bUnicode) {
  161.         lstrcpy(Buffer, UniBuffer);
  162.     } else {
  163.         WideCharToMultiByte(CP_ACP, 0, UniBuffer, Size, Buffer,
  164.                 Size, NULL, NULL);
  165.     }
  166.     free(UniBuffer);
  167.  
  168. } // ProcessData
  169.  
  170. //------------------------------------------------------------------
  171. BOOL IsThreadAdmin(void)
  172. {
  173.     HANDLE Token;
  174.     UCHAR InfoBuffer[1024];
  175.     PTOKEN_GROUPS ptgGroups = (PTOKEN_GROUPS)InfoBuffer;
  176.     DWORD dwInfoBufferSize;
  177.     PSID psidAdministrators;
  178.     SID_IDENTIFIER_AUTHORITY siaNtAuthority = SECURITY_NT_AUTHORITY;
  179.     UINT x;
  180.     BOOL bSuccess;
  181.  
  182.     if(!OpenThreadToken(GetCurrentThread(),TOKEN_READ,FALSE,&Token))
  183.        return(FALSE);
  184.  
  185.     bSuccess = GetTokenInformation(Token,TokenGroups,InfoBuffer,1024,
  186.                                    &dwInfoBufferSize);
  187.     CloseHandle(Token);
  188.  
  189.     if(!bSuccess) 
  190.         return FALSE;
  191.  
  192.     if(!AllocateAndInitializeSid(&siaNtAuthority, 2, 
  193.             SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS,
  194.             0, 0, 0, 0, 0, 0, &psidAdministrators))
  195.        return FALSE;
  196.  
  197.     bSuccess = FALSE;
  198.     for(x=0;x<ptgGroups->GroupCount;x++) {
  199.         if( EqualSid(psidAdministrators,ptgGroups->Groups[x].Sid) ){
  200.             bSuccess = TRUE;
  201.             break;
  202.          }
  203.     }
  204.     FreeSid(psidAdministrators);
  205.     return bSuccess;
  206. } // IsThreadAdmin
  207.  
  208. //-----------------------------------------------------------------
  209. VOID WINAPI ServiceHandler(DWORD fdwControl)
  210. {
  211.     // For simplicity and brevity, this service doesn't support
  212.     // pausing and continueing.
  213.  
  214.     switch(fdwControl) {
  215.         case SERVICE_CONTROL_STOP:
  216.             NotifySCM(SERVICE_STOP_PENDING, 0, 1);
  217.             SetEvent(hDoneEvent);
  218.             NotifySCM(SERVICE_STOPPED, 0, 0);
  219.             break;
  220.  
  221.         case SERVICE_CONTROL_INTERROGATE:
  222.             NotifySCM(dwCurrentState, 0, 0);
  223.             break;
  224.       
  225.         default:
  226.             break;
  227.     }
  228. } // ServiceHandler
  229.  
  230. //------------------------------------------------------------------
  231. BOOL NotifySCM(DWORD dwState,DWORD dwWin32ExitCode,DWORD dwProgress)
  232. {
  233.     SERVICE_STATUS ServiceStatus;
  234.  
  235.     ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
  236.     ServiceStatus.dwCurrentState = dwCurrentState = dwState;
  237.     ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | 
  238.                                        SERVICE_ACCEPT_SHUTDOWN;
  239.     ServiceStatus.dwWin32ExitCode = dwWin32ExitCode;
  240.     ServiceStatus.dwServiceSpecificExitCode = 0;
  241.     ServiceStatus.dwCheckPoint = dwProgress;
  242.     ServiceStatus.dwWaitHint = 5000;
  243.     return SetServiceStatus(hService, &ServiceStatus);
  244. } // NotifySCM
  245.  
  246.